#include "stdafx.h"
#include "ALGORITHM.h"

/*============================================================================
  File:      IDMPersist.Stubs.cpp
 
  Summary:   IDMPersist stubs to paste into implementation file
			 for class implementing the new algorithm

  Date:		 September 12, 2003
------------------------------------------------------------------------------
  This file is part of the Microsoft SQL Server Code Samples.
 
  Copyright (C) 2003 Microsoft Corporation.  All rights reserved.
 
This source code is intended only as a supplement to Microsoft
Development Tools and/or on-line documentation.  See these other
materials for detailed information regarding Microsoft code samples.
 
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
============================================================================*/



////
//
// IDMPersist interface
//
////

// Persistence element ids for our algorithm

// Persist items
enum DM_PERSIST_ENUM
{
	DM_PAIRWISELINREG = DMPI_ALGORITHMSPECIFIC_BASE,
	DM_ATTRIBUTE_COUNT,
	DM_CASE_COUNT,
	DM_LRPARAM_VIEW,
	DM_LRPARAM_PRED,
	DM_SAMPLE_SD_VECTOR,
	DM_SAMPLE_MEAN_VECTOR,
	DM_MIN_VECTOR,
	DM_MAX_VECTOR,
	DM_POSTERIOR_SD_VECTOR
};

// Helper functions for loading/saving a matrix of regression parameters

STDMETHODIMP	LoadVvlrparam(DM_PERSIST_ITEM		dmpersistitem, 
							  UINT					cAttribute,
							  VVLRPARAM&			vvlrparam, 
							  IDMPersistenceReader* pidmpersistencereader)
{
	HRESULT hr;
	hr = pidmpersistencereader->OpenScope((DM_PERSIST_ITEM) dmpersistitem);		RETURN_ON_FAIL(hr);
	vvlrparam.resize(cAttribute);
	for (UINT iAttribute = 0; iAttribute < cAttribute; iAttribute++)
	{
		ULONG clrparam;
		hr = pidmpersistencereader->GetULong(&clrparam);							RETURN_ON_FAIL(hr);
		vvlrparam[iAttribute].resize(clrparam);
		for (UINT ilrparam = 0; ilrparam < clrparam; ilrparam++)
		{
			LRPARAM& lrparam = vvlrparam[iAttribute][ilrparam];

			// Save in order: score, slope, intercept, sd, regressor, target
			hr = pidmpersistencereader->GetDouble(&lrparam._dblScore);		RETURN_ON_FAIL(hr);
			hr = pidmpersistencereader->GetDouble(&lrparam._dblSlope);		RETURN_ON_FAIL(hr);
			hr = pidmpersistencereader->GetDouble(&lrparam._dblIntercept);	RETURN_ON_FAIL(hr);
			hr = pidmpersistencereader->GetDouble(&lrparam._dblSD);			RETURN_ON_FAIL(hr);

			hr = pidmpersistencereader->GetULong(&lrparam._iAttributeRegressor);	RETURN_ON_FAIL(hr);
			hr = pidmpersistencereader->GetULong(&lrparam._iAttributeTarget);		RETURN_ON_FAIL(hr);
		}
	}

	hr = pidmpersistencereader->CloseScope();	

	return hr;
}


STDMETHODIMP	SaveVvlrparam(DM_PERSIST_ITEM		dmpersistitem, 
							  VVLRPARAM&			vvlrparam, 
							  IDMPersistenceWriter* pidmpersistencewriter)
{
	HRESULT hr;

	hr = pidmpersistencewriter->OpenScope((DM_PERSIST_ITEM) dmpersistitem);	RETURN_ON_FAIL(hr);
	for (UINT iAttribute = 0; iAttribute < vvlrparam.size(); iAttribute++)
	{
		ULONG clrparam = (ULONG) vvlrparam[iAttribute].size();
		hr = pidmpersistencewriter->SetULong(clrparam);						RETURN_ON_FAIL(hr);
		for (UINT ilrparam = 0; ilrparam < clrparam; ilrparam++)
		{
			LRPARAM& lrparam = vvlrparam[iAttribute][ilrparam];

			// Save in order: score, slope, intercept, sd, regressor, target
			hr = pidmpersistencewriter->SetDouble(lrparam._dblScore);		RETURN_ON_FAIL(hr);
			hr = pidmpersistencewriter->SetDouble(lrparam._dblSlope);		RETURN_ON_FAIL(hr);
			hr = pidmpersistencewriter->SetDouble(lrparam._dblIntercept);	RETURN_ON_FAIL(hr);
			hr = pidmpersistencewriter->SetDouble(lrparam._dblSD);			RETURN_ON_FAIL(hr);

			hr = pidmpersistencewriter->SetULong(lrparam._iAttributeRegressor);	RETURN_ON_FAIL(hr);
			hr = pidmpersistencewriter->SetULong(lrparam._iAttributeTarget);		RETURN_ON_FAIL(hr);
		}
	}

	hr = pidmpersistencewriter->CloseScope();	
	return hr;
}

STDMETHODIMP	LoadVdbl(DM_PERSIST_ITEM		dmpersistitem, 
						 VDBL&					vdbl, 
						 IDMPersistenceReader*	pidmpersistencereader)
{
	HRESULT hr;

	hr = pidmpersistencereader->OpenScope((DM_PERSIST_ITEM) dmpersistitem);	
	RETURN_ON_FAIL(hr);

	ULONG cdbl;
	hr = pidmpersistencereader->GetULong(&cdbl);						
	RETURN_ON_FAIL(hr);

	vdbl.resize(cdbl);
	for (UINT idbl = 0; idbl < cdbl; idbl++)
	{
		hr = pidmpersistencereader->GetDouble(&vdbl[idbl]);						
		RETURN_ON_FAIL(hr);
	}

	hr = pidmpersistencereader->CloseScope();	
	return hr;
}

STDMETHODIMP	SaveVdbl(DM_PERSIST_ITEM		dmpersistitem, 
						 VDBL&					vdbl, 
						 IDMPersistenceWriter*	pidmpersistencewriter)
{
	HRESULT hr;

	hr = pidmpersistencewriter->OpenScope((DM_PERSIST_ITEM) dmpersistitem);	
	RETURN_ON_FAIL(hr);

	hr = pidmpersistencewriter->SetULong((ULONG) vdbl.size());						
	RETURN_ON_FAIL(hr);

	for (UINT idbl = 0; idbl < vdbl.size(); idbl++)
	{
		hr = pidmpersistencewriter->SetDouble(vdbl[idbl]);						
		RETURN_ON_FAIL(hr);
	}

	hr = pidmpersistencewriter->CloseScope();	
	return hr;
}


////
//
// IDMPersist interface
//
////

STDMETHODIMP	ALGORITHM::Load(	
				IDMContextServices*		in_pContext,
				IDMPersistenceReader*	in_pReader	)
{
	// Load your model using the IDMPersistenceReader interface. 
	_lrpmodel.SetAllocator(*this);
	HRESULT hr = in_pReader->OpenScope((DM_PERSIST_ITEM) DM_PAIRWISELINREG);
	RETURN_ON_FAIL(hr);

	// Number of attributes
	hr = in_pReader->OpenScope((DM_PERSIST_ITEM) DM_ATTRIBUTE_COUNT);	RETURN_ON_FAIL(hr);
	hr = in_pReader->GetULong(&_lrpmodel._cAttribute);							RETURN_ON_FAIL(hr);
	hr = in_pReader->CloseScope();										RETURN_ON_FAIL(hr);

	// Number of cases
	hr = in_pReader->OpenScope((DM_PERSIST_ITEM) DM_CASE_COUNT);		RETURN_ON_FAIL(hr);
	hr = in_pReader->GetULong(&_lrpmodel._cCase);						RETURN_ON_FAIL(hr);
	hr = in_pReader->CloseScope();										RETURN_ON_FAIL(hr);

	// Viewing parameters
 	hr = LoadVvlrparam(DM_LRPARAM_VIEW, _lrpmodel._cAttribute, _lrpmodel._vvlrparamView, in_pReader);
	RETURN_ON_FAIL(hr);
	hr = LoadVvlrparam(DM_LRPARAM_PRED, _lrpmodel._cAttribute, _lrpmodel._vvlrparamView, in_pReader);

	// Sample mean/SD
	hr = LoadVdbl(DM_SAMPLE_SD_VECTOR, _lrpmodel._vdblSampleSD, in_pReader);
	RETURN_ON_FAIL(hr);

	hr = LoadVdbl(DM_SAMPLE_MEAN_VECTOR, _lrpmodel._vdblSampleMean, in_pReader);
	RETURN_ON_FAIL(hr);

	// Min/Max
	hr = LoadVdbl(DM_MIN_VECTOR, _lrpmodel._vdblMin, in_pReader);
	RETURN_ON_FAIL(hr);

	hr = LoadVdbl(DM_MAX_VECTOR, _lrpmodel._vdblMax, in_pReader);
	RETURN_ON_FAIL(hr);

	// Posterior SD
	hr = LoadVdbl(DM_POSTERIOR_SD_VECTOR, _lrpmodel._vdblPostSD, in_pReader);
	RETURN_ON_FAIL(hr);

	hr = in_pReader->CloseScope(); // DM_PAIRWISELINREG
	
	return S_OK;
}

STDMETHODIMP	ALGORITHM::Save(	
				IDMContextServices*		in_pContext,
				IDMPersistenceWriter*	in_pWriter	)
{
	// Save your model using the IDMPersistenceWriter interface.
	HRESULT hr = in_pWriter->OpenScope((DM_PERSIST_ITEM) DM_PAIRWISELINREG);
	RETURN_ON_FAIL(hr);

	// Number of attributes
	hr = in_pWriter->OpenScope((DM_PERSIST_ITEM) DM_ATTRIBUTE_COUNT);	RETURN_ON_FAIL(hr);
	hr = in_pWriter->SetULong(_lrpmodel._cAttribute);								RETURN_ON_FAIL(hr);
	hr = in_pWriter->CloseScope();										RETURN_ON_FAIL(hr);

	// Number of cases
	hr = in_pWriter->OpenScope((DM_PERSIST_ITEM) DM_CASE_COUNT);		RETURN_ON_FAIL(hr);
	hr = in_pWriter->SetULong(_lrpmodel._cCase);						RETURN_ON_FAIL(hr);
	hr = in_pWriter->CloseScope();										RETURN_ON_FAIL(hr);

	// Viewing parameters
	hr = SaveVvlrparam(DM_LRPARAM_VIEW, _lrpmodel._vvlrparamView, in_pWriter);
	RETURN_ON_FAIL(hr);
	hr = SaveVvlrparam(DM_LRPARAM_PRED, _lrpmodel._vvlrparamView, in_pWriter);

	// Sample mean/SD
	hr = SaveVdbl(DM_SAMPLE_SD_VECTOR, _lrpmodel._vdblSampleSD, in_pWriter);
	RETURN_ON_FAIL(hr);
	hr = SaveVdbl(DM_SAMPLE_MEAN_VECTOR, _lrpmodel._vdblSampleMean, in_pWriter);
	RETURN_ON_FAIL(hr);

	// Min/Max
	hr = SaveVdbl(DM_MIN_VECTOR, _lrpmodel._vdblMin, in_pWriter);
	RETURN_ON_FAIL(hr);
	hr = SaveVdbl(DM_MAX_VECTOR, _lrpmodel._vdblMax, in_pWriter);
	RETURN_ON_FAIL(hr);

	// Posterior SD
	hr = SaveVdbl(DM_POSTERIOR_SD_VECTOR, _lrpmodel._vdblPostSD, in_pWriter);
	RETURN_ON_FAIL(hr);
	hr = in_pWriter->CloseScope(); // DM_PAIRWISELINREG
	
	return S_OK;
}

